package thread;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.swing.JFrame;

public class FireWork {
    private JFrame jf; // 用于绘制界面
    private ArrayList<Particle> particles = new ArrayList<>();
    private int startX = 80, startY = 700;
    private double dt = 0.1d;
    Lock lock = new ReentrantLock();

    public FireWork(JFrame jf) {
        this.jf = jf;
        setListenerToFrame(this.jf);
    }

    // 对外暴露的操作
    public void draw() {
        /*
         * 利用缓冲绘图，减少卡顿 就是将多个点先画在一张图片上 之后再在主界面上绘制这副图片
         */
        lock.lock();
        try {
            BufferedImage img = new BufferedImage(jf.getWidth(), jf.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics bg = img.getGraphics();
            for (int i = 0; i < particles.size(); ++i) {
                Particle p = particles.get(i);
                p.age += 1;
                if (p.age >= p.life) {
                    particles.remove(i);
                }
                int r = p.color.getRGB();
                r -= new Random().nextInt(2000) + 2000;
                Color c = new Color(r);
                p.color = c;
                p.pos = p.pos.add(p.velocity.multi(dt));
                p.velocity = p.velocity.add(p.acceleration.multi(dt));
                bg.setColor(p.color);
                bg.fillOval(p.getX(), p.getY(), p.size, p.size);
            }
            jf.getGraphics().drawImage(img, 0, 0, null);
            TimeUnit.MILLISECONDS.sleep(5);
        } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); }

    }

    private void setListenerToFrame(JFrame jf) {
        jf.addMouseListener(new MouseAdapter() {
//            @Override
//            public void mouseClicked(MouseEvent e) {
//                super.mouseClicked(e);
//                int sX = e.getX(), sY = e.getY();
//                int bound = new Random().nextInt(100) + 80;
//                for (int i = 0; i < bound; ++i) {
//                    particles.add(makeParticle(sX, sY));
//                }
//            }

            @Override
            public void mousePressed(MouseEvent e) {
                super.mousePressed(e);
                int sX = e.getX(), sY = e.getY();
                int bound = new Random().nextInt(100) + 80;
                for (int i = 0; i < bound; ++i) {
                    particles.add(makeParticle(sX, sY));
                }
            }
        });
    }

    private Particle makeParticle(int sX, int sY) {
        Particle tmp = new Particle();
        tmp.pos = new Vec(sX, sY);
        tmp.velocity = randomDirection().multi(20);
        tmp.acceleration = randomDirection();
        tmp.life = new Random().nextInt(100) + 50;
        tmp.age = 0;
        tmp.size = 10 + new Random().nextInt(10);
        tmp.color = new Color(new Random().nextInt(3000) + 10);
        return tmp;
    }

    private Vec randomDirection() {
        double theta = Math.random() * 2 * Math.PI;
        return new Vec(Math.cos(theta), Math.sin(theta));
    }
}
